<script lang="ts" setup>
import type { RoleApi, UserApi } from '#/api/types';

import { ref, watch } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';

import { Card, Checkbox, Empty, message, Spin } from 'ant-design-vue';

import { getRoleListApi } from '#/api/core/modules/role';
import { assignUserRolesApi, getUserRolesApi } from '#/api/core/modules/user';
import { $t } from '#/locales';

const emit = defineEmits<{
  (e: 'success'): void;
}>();

const userData = ref<UserApi.UserInfoDetailVO>();
const loading = ref(false);
const roles = ref<RoleApi.RoleVO[]>([]);
const selectedRoleIds = ref<string[]>([]);
const originalRoleIds = ref<number[]>([]);
const userId = ref<number>();

// 监听用户ID变化重新加载角色数据
watch(
  () => userId.value,
  (newUserId) => {
    if (newUserId) {
      loadData();
    }
  },
  { immediate: false },
);

const [Drawer, drawerApi] = useVbenDrawer({
  title: $t('ui.modal.roleAssign'),
  async onConfirm() {
    if (!userId.value) return false;

    try {
      drawerApi.setState({ loading: true });

      // 将字符串数组转为数字数组
      const roleIds = selectedRoleIds.value.map(Number);

      // 调用API分配角色
      const result = await assignUserRolesApi({
        userId: userId.value,
        roleIds,
      });

      if (result.success) {
        message.success($t('common.operationSuccess'));
        emit('success');
        drawerApi.close();
        return true;
      } else {
        return false;
      }
    } catch {
      return false;
    } finally {
      drawerApi.setState({ loading: false });
    }
  },

  onOpenChange(isOpen) {
    if (isOpen) {
      const data = drawerApi.getData<UserApi.UserInfoDetailVO>();
      if (data && data.id) {
        userData.value = data;
        userId.value = data.id;
        // 更新抽屉标题
        drawerApi.setState({
          title: `${$t('ui.modal.roleAssign')}: ${data.username}`,
        });
        // 加载用户当前角色和所有可用角色
        loadData();
      }
    } else {
      // 关闭时清空数据
      selectedRoleIds.value = [];
      originalRoleIds.value = [];
      roles.value = [];
      userData.value = undefined;
    }
  },
});

// 加载角色数据
async function loadData() {
  loading.value = true;
  try {
    // 同时加载所有角色和用户已分配的角色
    if (userId.value) {
      await Promise.all([loadAllRoles(), loadUserRoles(userId.value)]);
    }
  } catch (error) {
    console.error('加载角色数据失败:', error);
    message.error($t('common.loadFailed'));
  } finally {
    loading.value = false;
  }
}

// 加载所有角色
async function loadAllRoles() {
  try {
    // 加载所有角色
    const roleResult = await getRoleListApi({
      current: 1,
      pageSize: 100,
      status: 1, // 只获取启用的角色
    });

    // 处理不同的数据结构
    let roleRecords: RoleApi.RoleVO[] = [];

    if (Array.isArray(roleResult)) {
      roleRecords = roleResult;
    } else if (roleResult && typeof roleResult === 'object') {
      if ('records' in roleResult) {
        roleRecords = roleResult.records as RoleApi.RoleVO[];
      } else if ('data' in roleResult && roleResult.data) {
        const data = roleResult.data;
        if (Array.isArray(data)) {
          roleRecords = data;
        } else if (data && 'records' in data && Array.isArray(data.records)) {
          roleRecords = data.records;
        }
      }
    }

    roles.value = roleRecords;
  } catch (error) {
    console.error('加载所有角色失败:', error);
    message.error($t('common.loadFailed'));
  }
}

// 加载用户已分配的角色
async function loadUserRoles(userId: number) {
  try {
    const userRolesResult = await getUserRolesApi(userId);

    // 处理不同的返回结构
    let userRoles: RoleApi.RoleVO[] = [];

    if (Array.isArray(userRolesResult)) {
      userRoles = userRolesResult;
    } else if (
      userRolesResult &&
      typeof userRolesResult === 'object' &&
      'data' in userRolesResult &&
      Array.isArray(userRolesResult.data)
    ) {
      userRoles = userRolesResult.data;
    }

    // 提取角色ID并转为字符串
    selectedRoleIds.value = userRoles
      .map((role) => (role.id ? role.id.toString() : ''))
      .filter(Boolean);

    // 保存原始角色ID，用于比对变更
    originalRoleIds.value = userRoles
      .map((role) => role.id as number)
      .filter(Boolean);
  } catch (error) {
    console.error('加载用户角色失败:', error);
    message.error($t('common.loadFailed'));
  }
}

// 切换角色选择状态
function toggleRoleSelection(roleId: string) {
  const index = selectedRoleIds.value.indexOf(roleId);
  if (index === -1) {
    selectedRoleIds.value.push(roleId);
  } else {
    selectedRoleIds.value.splice(index, 1);
  }
}

// 检查角色是否被选中
function isRoleSelected(roleId: string): boolean {
  return selectedRoleIds.value.includes(roleId);
}

// 暴露抽屉API给父组件
defineExpose({
  drawerApi,
});
</script>

<template>
  <Drawer class="w-[600px]">
    <div>
      <div class="mb-4">
        <div class="flex items-center">
          <span class="text-lg font-medium">{{ userData?.username }}</span>
          <span class="ml-2 text-sm text-gray-500">
            {{ userData?.nickname ? `(${userData.nickname})` : '' }}
          </span>
        </div>
        <p class="text-sm text-gray-500">{{ userData?.email }}</p>
      </div>

      <Spin :spinning="loading">
        <div class="role-container">
          <div class="mb-3 text-sm text-gray-500">
            请选择要分配给该用户的角色
          </div>

          <Empty v-if="roles.length === 0" :description="$t('common.noData')" />

          <div v-else class="role-list-container">
            <Card
              :bordered="true"
              :head-style="{ background: '#f6f8fa', padding: '2px 16px' }"
              size="small"
              :body-style="{ padding: '0' }"
            >
              <template #title>
                <div class="flex items-center">
                  <span class="font-medium">角色列表</span>
                </div>
              </template>

              <!-- 角色列表 -->
              <div class="role-items">
                <div
                  v-for="role in roles"
                  :key="role.id"
                  class="role-item"
                  @click="toggleRoleSelection(role.id?.toString() || '')"
                >
                  <Checkbox
                    :checked="isRoleSelected(role.id?.toString() || '')"
                    @click.stop
                    @change="
                      (e) =>
                        e.target.checked
                          ? selectedRoleIds.push(role.id?.toString() || '')
                          : selectedRoleIds.splice(
                              selectedRoleIds.indexOf(
                                role.id?.toString() || '',
                              ),
                              1,
                            )
                    "
                  >
                    <div class="role-info">
                      <div class="role-name">
                        {{ role.name }}
                        <span class="role-code">{{ role.code }}</span>
                      </div>
                      <div class="role-desc">{{ role.description }}</div>
                    </div>
                  </Checkbox>
                </div>
              </div>
            </Card>
          </div>
        </div>
      </Spin>
    </div>
  </Drawer>
</template>

<style scoped>
.role-container {
  overflow-y: auto;
}

.role-list-container {
  margin-bottom: 1rem;
}

.role-items {
  max-height: 400px;
  overflow-y: auto;
}

.role-item {
  padding: 12px 16px;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
  transition: background-color 0.2s;
}

.role-item:hover {
  background-color: #f9f9f9;
}

.role-item:last-child {
  border-bottom: none;
}

.role-info {
  display: flex;
  flex-direction: column;
}

.role-name {
  font-weight: 500;
}

.role-code {
  margin-left: 8px;
  font-size: 12px;
  color: #8c8c8c;
}

.role-desc {
  margin-top: 4px;
  font-size: 12px;
  color: #8c8c8c;
}
</style>
